Skip to main content

Unions & Joins

I. Unions

The UNION operator combines the result sets of two or more SELECT statements. It removes duplicate rows between the various SELECT statements and returns only distinct rows. If you want to include duplicates, you can use UNION ALL.

The result sets from each SELECT statement are essentially stacked on top of each other. Each result set contributes its rows to a combined result set, maintaining the column structure defined in the SELECT statements.

-- SYNTAX for UNION
SELECT column1, column2, ...
FROM table1
UNION
SELECT column1, column2, ...
FROM table2;

Example 1: Find a list of employee and branch names.

SELECT first_name 
FROM employees;
UNION
SELECT branch_name
FROM branches;

Rules and Considerations

  1. Same Number of Columns: All SELECT statements in a UNION must have the same number of columns in the result sets.
-- This will result in an error because the number of columns does not match.
SELECT name, department FROM employees
UNION
SELECT name FROM branches;
  1. Similar Data Types: The columns from each SELECT statement must have compatible data types. If they are not compatible, an error will occur.
-- This will result in an error if hire_date is a date and salary is numeric.
SELECT hire_date FROM employees
UNION
SELECT salary FROM employees;
  1. Column Names and Order: The column names in the result set are taken from the first SELECT statement.
SELECT name AS employee_name FROM employees
UNION
SELECT name FROM branches;

→ The column name in the result set will be employee_name because it is specified in the first SELECT statement.

  1. UNION ALL is generally faster than UNION because it does not perform the additional step of removing duplicates. Use UNION ALL if you do not need to eliminate duplicates and want to optimize performance.

II. Joins

Joins are used to combine rows from two or more tables based on a related column between them. When you join tables in SQL, you're effectively creating a temporary, combined view of the data from which you can query.

graph TD
A[Table A] --> C[Join Operation]
B[Table B] --> C
C --> D[Temporary Result Set]
D --> E[Further Operations]
E --> F[Query Result]
style D fill:#f9f,stroke:#333,stroke-width:4px

Further operations here include WHERE, SELECT, GROUP BY, HAVING, ORDER BY, LIMIT, etc.

Types of Joins

Take two tables, employees, and branches

emp_idfirst_name
1Alice
2Bob
3Carol
4Dave
branch_namemanager_id
North1
South3
East5

1. Inner Join

Returns only the rows that have matching values in both tables. JOIN will default to INNER JOIN.

SELECT employees.emp_id, employees.first_name, branches.branch_name
FROM employees
INNER JOIN branches
ON employees.emp_id = branches.manager_id;

Results:

emp_idfirst_namebranch_name
1AliceNorth
3CarolSouth

2. Left Join (Left Outer Join)

Returns all rows from the left table (employees) and the matched rows from the right table (branches). If no match is found, the result is NULL on the side of the branch.

SELECT employees.emp_id, employees.first_name, branches.branch_name
FROM employees
LEFT JOIN branches
ON employees.emp_id = branches.manager_id;

Results:

emp_idfirst_namebranch_name
1AliceNorth
2BobNULL
3CarolSouth
4DaveNULL

3. Right Join (Right Outer Join)

Returns all rows from the right table (branches) and the matched rows from the left table (employees). If no match is found, the result is NULL on the side of the employees.

SELECT employees.emp_id, employees.first_name, branches.branch_name
FROM employees
RIGHT JOIN branches
ON employees.emp_id = branches.manager_id;

Results:

emp_idfirst_ namebranch_name
1AliceNorth
3CarolSouth
NULLNULLEast

4. Full Join (Full Outer Join)

Returns all rows when there is a match in either the left or right table. If there is no match, the result is NULL on the side without a match.

SELECT employees.emp_id, employees.first_name, branches.branch_name
FROM employees
FULL JOIN branches
ON employees.emp_id = branches.manager_id;

Results:

emp_idfirst_namebranch_name
1AliceNorth
2BobNULL
3CarolSouth
4DaveNULL
NULLNULLEast

5. Cross Join

Returns the Cartesian product of the two tables, meaning every possible combination of rows.

SELECT employees.emp_id, employees.first_name, branches.branch_name
FROM employees
CROSS JOIN branches;

Results:

emp_idfirst_namebranch_name
1AliceNorth
1AliceSouth
1AliceEast
2BobNorth
2BobSouth
2BobEast
3CarolNorth
3CarolSouth
3CarolEast
4DaveNorth
4DaveSouth
4DaveEast

5. Self Join

A self join is a join in which a table is joined with itself. This technique is useful when you need to compare rows within the same table or establish a relationship between rows of the same table.

Suppose we have an employees table with the following structure:

emp_idfirst_namemanager_id
1AliceNULL
2Bob1
3Carol1
4Dave2
5Eve2

By using self join, we can find each employee and their corresponding manager’s name.

Table Aliases:

  • e represents the employees.
  • m represents the managers.

JOIN Condition:

  • ON e.manager_id = m.emp_id: Matches the manager_id from the e table (employees) with the emp_id from the m table (managers).

LEFT JOIN: Ensures that employees without managers (e.g., Alice) are still included in the result.

SELECT e.emp_id AS employee_id, e.first_name AS employee_name,
m.first_name AS manager_name
FROM employees e
LEFT JOIN employees m
ON e.manager_id = m.emp_id;

Result:

employee_idemployee_namesmanager_name
1AliceNULL
2BobAlice
3CarolAlice
4DaveBob
5EveBob

Joining Multiple Tables

You can use Join to join more than 2 tables together.

select distinct m.firstname || ' ' || m.surname as member, 
f.name as facility
from cd.members m
join cd.bookings b on m.memid = b.memid
join cd.facilities f on b.facid = f.facid;